package com.wondertek.service.service.business.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wondertek.common.base.Result;
import com.wondertek.common.exception.AppException;
import com.wondertek.common.log.AutoLogUtil;
import com.wondertek.service.dto.app.req.AppAccessoryPageReq;
import com.wondertek.service.dto.business.req.AccessoryAddReq;
import com.wondertek.service.dto.business.req.AccessoryPageReq;
import com.wondertek.service.dto.business.res.AccessoryPageRes;
import com.wondertek.service.dto.business.res.SiteDeviceAccessoryRes;
import com.wondertek.service.entity.business.*;
import com.wondertek.service.mapper.business.AccessoryMapper;
import com.wondertek.service.sdk.iotdh.dto.req.*;
import com.wondertek.service.sdk.iotdh.dto.res.GetAccessoryInfoRes;
import com.wondertek.service.sdk.iotdh.dto.res.doorDetector.SetDoorDetectorAccessoryInfoReq;
import com.wondertek.service.sdk.iotdh.dto.res.doorDetectorPlus.SetDoorDetectorPlusAccessoryInfoReq;
import com.wondertek.service.sdk.iotdh.dto.res.pir.SetPIRAccessoryInfoReq;
import com.wondertek.service.sdk.iotdh.service.DhDeviceService;
import com.wondertek.service.service.business.AccessoryService;
import com.wondertek.service.service.business.DeviceService;
import com.wondertek.service.service.business.RentalService;
import com.wondertek.service.service.business.RoomService;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @description:
 * @author: qinjianhui
 * @create: 2024-07-31 14:21
 **/
@Service
public class AccessoryServiceImpl extends ServiceImpl<AccessoryMapper, AccessoryPo> implements AccessoryService {

    @Resource
    private DhDeviceService dhDeviceService;

    @Resource
    private RoomService roomService;

    @Resource
    private DeviceService deviceService;

    @Resource
    private AccessoryMapper accessoryMapper;

    @Resource
    private RentalService rentalService;

    @Override
    public void setDoorDetectorAccessoryInfo(SetDoorDetectorAccessoryInfoReq req) {
        dhDeviceService.setDoorDetectorAccessoryInfo(req);
        updateArmByCode(req.getAccessoryInfos().get(0).getId(),req.getAccessoryInfos().get(0).getArmingInfo().get(0).getEnable());
    }

    @Override
    public void setDoorDetectorPlusAccessoryInfo(SetDoorDetectorPlusAccessoryInfoReq req) {
        dhDeviceService.setDoorDetectorPlusAccessoryInfo(req);
        updateArmByCode(req.getAccessoryInfos().get(0).getId(),req.getAccessoryInfos().get(0).getArmingInfo().get(0).getEnable());
    }

    @Override
    public void setPIRAccessoryInfo(SetPIRAccessoryInfoReq req) {
        dhDeviceService.setPIRAccessoryInfo(req);
        updateArmByCode(req.getAccessoryInfos().get(0).getId(),req.getAccessoryInfos().get(0).getArmingInfo().get(0).getEnable());
    }

    private void updateArmByCode(String code, boolean arm){
        LambdaQueryWrapper<AccessoryPo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(AccessoryPo::getAccessoryCode,code);
        List<AccessoryPo> list = this.list(lambdaQueryWrapper);
        if(CollectionUtils.isNotEmpty(list)){
            AccessoryPo accessoryPo = list.get(0);
            accessoryPo.setArmingEnable(arm);
            this.updateById(accessoryPo);
        }
    }

    /*
     * 根据sn查询已删除的配件
     * */
    @Override
    public List<AccessoryPo> selectBysql(String code){
        return accessoryMapper.selectBysql(code);
    }

    /*
     * 挂载配件
     * */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setAccessoryPair(SetAccessoryPairReq req) {
        //记录日志
        DevicePo devicePo = new DevicePo();
        devicePo.setSnCode(req.getDeviceId());
        SiteDeviceAccessoryRes res = deviceService.selectSiteDevice(devicePo);
        AutoLogUtil.save("sys","log.accessory.insert","配件sn码:"+req.getAccessoryInfo().getId(),
                res.getSiteName(),res.getDeviceSn(),res.getSiteId(),req.getAccessoryInfo().getId());
        //先查询该分区下是否已添加此配件
        LambdaQueryWrapper<AccessoryPo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AccessoryPo::getRoomId,req.getRoomId());
        queryWrapper.eq(AccessoryPo::getIsDelete,0);
        queryWrapper.eq(AccessoryPo::getAccessoryCode,req.getAccessoryInfo().getId());
        List<AccessoryPo> list = this.list(queryWrapper);
        if(CollectionUtils.isNotEmpty(list)){
            throw new AppException("accessory.exist");
        }
        RoomPo byId = roomService.getById(req.getRoomId());
        req.getAccessoryInfo().setAreaId(byId.getRoomCode());
        //先去开起分区
        AetAreaInfoReq aetAreaInfoReq = new AetAreaInfoReq();
        aetAreaInfoReq.setDeviceId(req.getDeviceId());
        aetAreaInfoReq.setAreaEnable(true);
        aetAreaInfoReq.setAreaId(byId.getRoomCode());
        dhDeviceService.setAreaInfo(aetAreaInfoReq);
        //挂载
        dhDeviceService.setAccessoryPair(req);
        AccessoryPo po = new AccessoryPo();
        po.setAccessoryCode(req.getAccessoryInfo().getId());
        po.setAccessoryName(req.getAccessoryInfo().getName());
        po.setIsDelete(0);
        po.setRoomId(req.getRoomId());
        po.setModel(req.getAccessoryInfo().getModel());
        po.setSensorType(req.getAccessoryInfo().getSensorType());
        po.setWirelessType(req.getAccessoryInfo().getWirelessType());
        po.setAccessoryType(req.getAccessoryType());
        po.setSnCode(req.getAccessoryInfo().getId());
        po.setStatus(0);
        po.setArmingEnable(false);
        this.save(po);
    }

    /*
     * 配件详情
     * */
    @Override
    public Result<GetAccessoryInfoRes> detail(String id){
        GetAccessoryInfoRes res = new GetAccessoryInfoRes();
        AccessoryPo acc = this.getById(id);
        if(acc!=null){
            RoomPo room = roomService.getById(acc.getRoomId());
            GetAccessoryInfoReq req = new GetAccessoryInfoReq();
            DevicePo device = deviceService.getById(room.getDeviceId());
            req.setDeviceId(device.getSnCode());
            List<String> accessoryIds = new ArrayList<>();
            accessoryIds.add(acc.getAccessoryCode());
            req.setAccessoryIds(accessoryIds);
            Result<List<GetAccessoryInfoRes>> accessoryInfo = dhDeviceService.getAccessoryInfo(req);
            List<GetAccessoryInfoRes> list = accessoryInfo.getData();
            if(CollectionUtils.isNotEmpty(list)){
                res = list.get(0);
                //根据分区查询租赁时间
                LambdaQueryWrapper<RentalDevicePo> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(RentalDevicePo::getRoomId,acc.getRoomId());
                wrapper.eq(RentalDevicePo::getIsDelete,0);
                List<RentalDevicePo> list1 = rentalService.list(wrapper);
                if (CollectionUtils.isNotEmpty(list1)) {
                    RentalDevicePo rentalDevicePo = list1.get(0);
                    res.setStartDate(rentalDevicePo.getStartDate());
                    res.setEndDate(rentalDevicePo.getEndDate());
                }
            }
        }
        return Result.success(res);
    }

    /*
     * 分页查询
     * */
    @Override
    public Page<AccessoryPo> page(AppAccessoryPageReq req) {
        LambdaQueryWrapper<AccessoryPo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AccessoryPo::getRoomId, req.getRoomId());
        wrapper.eq(AccessoryPo::getIsDelete, 0);
        return this.page(new Page<>(req.getPageNo(), req.getPageSize()), wrapper);
    }

    /**
     * web分页查询配件
     * @param req
     * @return
     */
    public Page<AccessoryPageRes> webPage(AccessoryPageReq req){
        Page<AccessoryPageRes> resPage = accessoryMapper.webPage(req, new Page(req.getPageNo(), req.getPageSize()));
        List<AccessoryPageRes> list = resPage.getRecords();
        if(CollectionUtils.isNotEmpty(list)){
//            for(AccessoryPageRes res : list){
//                //查询配件状态
//                GetAccessoryInfoReq getAccessoryInfoReq = new GetAccessoryInfoReq();
//                getAccessoryInfoReq.setDeviceId(res.getDeviceSn());
//                List<String> accessoryIds = new ArrayList<>();
//                accessoryIds.add(res.getAccessoryCode());
//                getAccessoryInfoReq.setAccessoryIds(accessoryIds);
//                Result<List<GetAccessoryInfoRes>> accessoryInfo = dhDeviceService.getAccessoryInfo(getAccessoryInfoReq);
//                List<GetAccessoryInfoRes> infoResList = accessoryInfo.getData();
//                if (CollectionUtils.isNotEmpty(infoResList)){
//                    Integer status = infoResList.get(0).getOnline();
//                    if(status==2){
//                        res.setStatus(1);
//                    }else{
//                        res.setStatus(0);
//                    }
//                }
//            }
        }
        return resPage;
    }

    @Override
    public void addAccessory(AccessoryAddReq req) {

        System.out.println("req:"+req);

        //先验证邮箱是否已经注册
        LambdaQueryWrapper<AccessoryPo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AccessoryPo::getSnCode,req.getSnCode());
        wrapper.eq(AccessoryPo::getIsDelete,0);

        AccessoryPo one = this.getOne(wrapper);

        if(one != null){
            throw new AppException("accessory.exist");
        }


        String deviceSn = req.getSnCode();

        AccessoryPo accessoryPo = new AccessoryPo();
        BeanUtil.copyProperties(req, accessoryPo);
        accessoryPo.setIsDelete(0);
        accessoryPo.setArmingEnable(false);

        // 传值 accessory_code(配件sn) sn_code(网关设备sn)
        // 入库 accessory 配件表 accessory_code和sn_code 都是存的 配件sn码
        accessoryPo.setSnCode(accessoryPo.getAccessoryCode());


        try {
            GetAccessoryInfoReq getAccessoryInfoReq = new GetAccessoryInfoReq();
            getAccessoryInfoReq.setDeviceId(deviceSn);
            getAccessoryInfoReq.setAccessoryIds(new ArrayList(){{add(accessoryPo.getAccessoryCode());}});
            Result<List<GetAccessoryInfoRes>> accessoryInfo = dhDeviceService.getAccessoryInfo(getAccessoryInfoReq);
            List<GetAccessoryInfoRes> records = accessoryInfo.getData();

            GetAccessoryInfoRes getAccessoryInfoRes = records.get(0);

            Integer online = getAccessoryInfoRes.getOnline();

            accessoryPo.setStatus(online == 2 ? 1 : 0);
        }catch (Exception e){
            accessoryPo.setStatus(0);
        }
        this.save(accessoryPo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updAccessory(SetAccessoryAreaReq req) {
        //记录日志
        AccessoryPo accessoryPo = new AccessoryPo();
        accessoryPo.setAccessoryCode(req.getAccessoryId());
        SiteDeviceAccessoryRes res = deviceService.selectSiteDeviceAccessory(accessoryPo);
        AutoLogUtil.save("sys","log.accessory.update","配件sn码:"+res.getAccessorySn(),
                res.getSiteName(),res.getDeviceSn(),res.getSiteId(),res.getAccessorySn());
        //先去开起分区
        AetAreaInfoReq aetAreaInfoReq = new AetAreaInfoReq();
        aetAreaInfoReq.setDeviceId(req.getDeviceId());
        aetAreaInfoReq.setAreaEnable(true);
        aetAreaInfoReq.setAreaId(req.getAreaId());
        dhDeviceService.setAreaInfo(aetAreaInfoReq);
        //调用Dh修改配件
        dhDeviceService.setAccessoryArea(req);
        //查询设备
        LambdaQueryWrapper<DevicePo> devicePoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        devicePoLambdaQueryWrapper.eq(DevicePo::getSnCode,req.getDeviceId());
        devicePoLambdaQueryWrapper.eq(DevicePo::getIsDelete,0);
        List<DevicePo> devicePos = deviceService.list(devicePoLambdaQueryWrapper);
        if(CollectionUtils.isNotEmpty(devicePos)){
            //查询房间
            DevicePo devicePo = devicePos.get(0);
            LambdaQueryWrapper<RoomPo> roomLambdaQueryWrapper = new LambdaQueryWrapper<>();
            roomLambdaQueryWrapper.eq(RoomPo::getDeviceId,devicePo.getId());
            roomLambdaQueryWrapper.eq(RoomPo::getRoomCode,req.getAreaId());
            List<RoomPo> roomPos = roomService.list(roomLambdaQueryWrapper);
            if(CollectionUtils.isNotEmpty(roomPos)){
                RoomPo roomPo = roomPos.get(0);
                LambdaQueryWrapper<AccessoryPo> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(AccessoryPo::getAccessoryCode,req.getAccessoryId());
                List<AccessoryPo> accessoryPos = this.list(wrapper);
                if(CollectionUtils.isNotEmpty(accessoryPos)){
                    AccessoryPo one = accessoryPos.get(0);
                    one.setRoomId(roomPo.getId());
                    one.setAccessoryName(req.getAccessoryName());
                    this.updateById(one);
                }
            }
        }
    }

    @Override
    public void delAccessory(DeleteAccessoryReq req) {
        try {
            //先去查设备是否在线，设备离线不允许删除配件
            LambdaQueryWrapper<DevicePo> devicePoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            devicePoLambdaQueryWrapper.eq(DevicePo::getSnCode,req.getDeviceId());
            devicePoLambdaQueryWrapper.eq(DevicePo::getIsDelete,0);
            List<DevicePo> list = deviceService.list(devicePoLambdaQueryWrapper);
            if(CollectionUtils.isNotEmpty(list)){
                DevicePo devicePo = list.get(0);
                if(0==devicePo.getStatus()){
                    throw new AppException("device.offline.can.not.delete.accessory");
                }
            }
            //记录日志
            AccessoryPo accessoryPo = new AccessoryPo();
            accessoryPo.setAccessoryCode(req.getAccessoryId());
            SiteDeviceAccessoryRes res = deviceService.selectSiteDeviceAccessory(accessoryPo);
            AutoLogUtil.save("sys","log.accessory.delete","配件sn码:"+res.getAccessorySn(),
                    res.getSiteName(),res.getDeviceSn(),res.getSiteId(),res.getAccessorySn());
            //调用DH删除配件
            dhDeviceService.deleteAccessory(req);
            LambdaQueryWrapper<AccessoryPo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(AccessoryPo::getAccessoryCode,req.getAccessoryId());
            this.remove(wrapper);
        }catch (Exception e){
            //大华配件不存在时，删除本系统配件数据
            if("accessory not found".equals(e.getMessage())){
                LambdaQueryWrapper<AccessoryPo> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(AccessoryPo::getAccessoryCode,req.getAccessoryId());
                this.remove(wrapper);
            }else {
                throw e;
            }
        }
    }
}

